#include<stdio.h>#include<new>
using namespace std;char*gPool = NULL;void my_new_handler();int main(){
set_new_handler(my_new_handler);
gPool= new char[100*1024*1024];if(gPool!=NULL){printf("Pressure 101MB memory at %x\n",gPool);}char*p=NULL;for(int i=0;i<20;i++){
p=new char[100*1024*1024];printf("%d *100MB,p= %x\n",i+1,p);}printf("done.\n");return0;}void my_new_handler(){if(gPool!=NULL){printf("try ro get more memory ...\n");
delete[] gPool;
gPool=NULL;return;}else{printf("I can not help ...\n");
throw bad_alloc();}return;}
代码执行到第19次时,会分配内存失败,100*19=1.9G,而用于动态内存管理的内存最大为2G,所以...
to be continued...
#include <stdio.h>#include <new>
using namespace std;
class simple{
public:int m_nValue;staticvoid*operator new(size_t n);staticvoid* operator new (std::size_t n,char*file,int line);
};void*simple::operator new (std::size_t n,char* file,int line){printf("size: %d\nnew at %s,%d\n",n,file,line);return::operator new (n);}void*simple::operator new (size_t n){printf("size : %d\n",n);return::operator new (n);}
- C++程序中的存储空间可以分为静态/全局存储区,以及堆栈区和堆区,
self defining class of Operator new/delete
静态全局存储区和堆栈区的大小一般在程序编译阶段决定;Table of Contents
而堆区则随着程序的运行而动态的变化,每次程序运行都会有不同的行为,
动态内存管理的目的是为了有效地使用C++的特性提高内存管理效率,减少错误的发生。
下面讲一下new new[]和delete delete[]操作方法,
在这之前我们看一下这四个函数的声明:
声明决定了new和delete可以进行的操作,他们被声明于命名空间,于是可以像关键字一样使用。
new分配大小为size的内存,成功的话返回内存的起始地址。
而c++标准中没有规定是否要对获得的内存初始化,(这一点容易弄混,因为我们通常的标准时,分配时初始化操作)
这样的话,如果开发人员没有为分配的内存显式的赋初值,那么初始值的具体值就有赖于编译器的具体实现。
从上面的声明可以看出new的三种操作:
C++标准对内存分配失败有明确的规定,sys调用当前的new_handler() 函数,这个函数是通过set_new_handler()安装到系统中的,
系统规定new_handler要执行下面三个操作的一种:
1, 是new有更多的内存可用,然后返回。
2,抛出一个bad_alloc或其派生的异常。
3,调用abort()或者exit()推出。
下面举一个例子来说明:
代码执行到第19次时,会分配内存失败,100*19=1.9G,而用于动态内存管理的内存最大为2G,所以...
to be continued...
self defining class of Operator new/delete
当定义全局的operator new/delete时,程序中的所有内存分配释放将使用统一的方式。然而在某些情况下,程序希望创建不同的类对象时使用不用的内存分配方式,尤其是在某些要求内存分配效率的程序中,为此,可以通过类成员函数形式的operator new/delete重载来为一些特定的类实现这个类自己的operator new/delete. 而其他则保持使用系统默认的operator new/delete.